package com.example.logisticsingle.interceptor;

import com.example.logisticsingle.Config.SSOConfig;
import com.example.logisticsingle.String.StringUtils;
import com.example.logisticsingle.entity.SSOUser;
import com.example.logisticsingle.utils.SSOLoginHelper;

import com.example.logisticsingle.annotation.IgnoreLogin;
import com.example.logisticsingle.constants.Config;
import com.example.logisticsingle.constants.ResponseEnum;
import com.example.logisticsingle.dto.Result;
import com.example.logisticsingle.utils.JsonUtils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * token拦截器
 * @author Roskin
 *
 */
@Component
@Slf4j

public class LoginInterceptor extends HandlerInterceptorAdapter {
    @Value("${token.header}")
    private String tokenHeader = Config.DEFAULT_TOKEN_HEADER_STRING;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        log.info("请求路径:{}" ,request.getRequestURI());
        // 如果不是映射到方法直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        log.debug("Method:{},IgnoreLogin:{}",method.getName(),method.isAnnotationPresent(IgnoreLogin.class));
        // 判断接口是否需要登录
        if (method.isAnnotationPresent(IgnoreLogin.class)) {
            return true;
        }
        String token = request.getHeader(tokenHeader);
        if(StringUtils.isNull(token)) {
            token = request.getParameter("access_token");
        }
        log.info("Token:{},", token);
        SSOUser user = SSOLoginHelper.validateToken(token);
        if (StringUtils.isNull(token)||null==user) {
            log.error("必须要传token的接口,Token:{},请求路径{}", token, request.getRequestURI());
            String str = request.getHeader(Config.REQUEST_TYPE);
            String request_type = StringUtils.isNull(str)?request.getParameter(Config.REQUEST_TYPE):str;
            if(StringUtils.isNotNull(request_type) && Integer.valueOf(request_type)==Config.REQUEST_TYPE_WEB) {
                String loginPageURL = SSOConfig.LOGIN_URL;
                if(StringUtils.isNull(loginPageURL)) throw new Exception("请配置登录的URL");
                String referer = request.getRequestURI();
                String reditURL = (referer==loginPageURL)? loginPageURL:String.format("%s?%s=%s", loginPageURL,Config.REDIRECT_URL,
                        request.getRequestURL().toString());
                response.sendRedirect(reditURL);
            }else {
                response.setContentType("application/json;charset=utf-8");
                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                Result<?> result = new Result<>();
                result.setCode(ResponseEnum.TOKEN_INVALID.getCode());
                result.setStatus(false);
                result.setMessage("没有访问该接口的权限，请登录后访问");
                response.getWriter().write(JsonUtils.toJson(result));
            }
            return false;
        }
        request.setAttribute("currentUser", user);
        return true;
    }
}
